package com.k.base.jdk.stream.listmaptobean;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 统计数据
 * @author kivil
 */
public class ListMapToBeanTest {

    public List<TypeCountStatistics> listMapToBean(List<Map<String,Object>> list){
        List<TypeCountStatistics> result = new ArrayList<>();
        list.stream()
             // 1.过滤 去掉type=1 的数据
            .filter(s -> !"1".equals(String.valueOf(s.get("type"))))
            .collect(Collectors.toList()).stream()
             // 2.转换 Bean
            .map(itm -> {return  new TypeCountStatistics(Integer.parseInt(String.valueOf(itm.get("type"))),Integer.parseInt(String.valueOf(itm.get("count"))));})
            .collect(Collectors.groupingBy(a ->a.getType()))
            // 3.遍历求和
            .forEach((id,transfer)->{
                transfer.stream()
                        .reduce(
                                (c,d)->{
                                    return new TypeCountStatistics(c.getType(),c.getCount()+d.getCount());
                                }
                        )
                        .ifPresent(a->result.add(a));
            });
        return result;
    }

    public Map<Long,Long> listMapToBean2(List<Map<String,Object>> list){
        Map<Long,Long> r = list.stream().filter(s -> !"1".equals(String.valueOf(s.get("type"))))
                .collect(Collectors.groupingBy(a -> Long.parseLong(String.valueOf(a.get("type"))),
                        Collectors.summingLong(b->Long.parseLong(String.valueOf(b.get("count"))))));
        return r;
    }

    /**
     * 根据 type 求 count的最大，最小，平均 值
     * @param list data
     * @return     Map<Integer,IntSummaryStatistics>
     */
    public Map<Integer,IntSummaryStatistics> listMapToBean3(List<Map<String,Object>> list){
        Map<Integer,IntSummaryStatistics> o = list.stream()
                // 1.过滤 去掉type=1 的数据
                .filter(s -> !"1".equals(String.valueOf(s.get("type"))))
                .collect(Collectors.toList()).stream()
                // 2.转换 Bean
                .map(itm -> {return  new TypeCountStatistics(Integer.parseInt(String.valueOf(itm.get("type"))),Integer.parseInt(String.valueOf(itm.get("count"))));})
                // 3.统计求和
                .collect(Collectors.groupingBy(TypeCountStatistics::getType,Collectors.summarizingInt(b->b.getCount())))
                ;
        return o;
    }

    public Object listMapToBean4(List<Map<String,Object>> list){
        Object o = list.stream()
                // 1.过滤 去掉type=1 的数据
                .filter(s -> !"1".equals(String.valueOf(s.get("type"))))
                .collect(Collectors.toList()).stream()
                // 2.转换 Bean
                .map(itm -> {return  new TypeCountStatistics(Integer.parseInt(String.valueOf(itm.get("type"))),Integer.parseInt(String.valueOf(itm.get("count"))));})
                // 3.统计此 type 和 type有几条记录
                .collect(Collectors.groupingBy(
                            TypeCountStatistics::getType,
                            Collectors.counting()
                        )
                );
        System.out.println(o);
        return o;
    }

    /**
     * TODO
     * 多列统计
     */
    public void multiColumnStatistics(List<Map<String,Object>> list){
        Object obj = list.stream()
                .filter(s -> !"1".equals(String.valueOf(s.get("type"))))
                .map(itm -> {return  new TypeCountStatistics(Integer.parseInt(String.valueOf(itm.get("type"))),Integer.parseInt(String.valueOf(itm.get("count"))));})
                .collect(
                        Collectors.groupingBy(n->{
                            //return new TypeCountStatistics(n.getType(),n.getCount());
                            return n.getType();
                            }
                        ,Collectors.collectingAndThen(Collectors.toList(),m->{
                                    long totalCount = m.stream().count();
                                    // COUNT 字段统计
                                    long sum = m.stream().mapToInt(a->a.getCount()).sum();
                                    int min = m.stream().mapToInt(a->a.getCount()).min().getAsInt();
                                    int max = m.stream().mapToInt(a->a.getCount()).max().getAsInt();
                                    double avg = m.stream().mapToDouble(a->a.getCount()).average().getAsDouble();

                                    // type 字段统计
                                    long typesum = m.stream().mapToInt(a->a.getType()).sum();

                                    Map r = new HashMap();
                                    r.put("totalCount",totalCount);
                                    r.put("sum",sum);
                                    r.put("min",min);
                                    r.put("max",max);
                                    r.put("avg",avg);
                                    r.put("typesum",typesum);
                                    return r;
                                })
                        )
                );
        System.out.println(obj);

    }


    // ================ Test =================

    public List<Map<String,Object>> getTestData(){
        List<Map<String,Object>> list = new ArrayList<>();
        for(int i = 0;i<10;i++){
            Map<String,Object> map = new HashMap<>();
            map.put("id",i+1);
            if(i<4){
                map.put("type",1);
                map.put("count",i);
                list.add(map);
            }else if(i<8){
                map.put("type",2);
                map.put("count",i);
                list.add(map);
            }else if(i<10){
                map.put("type",3);
                map.put("count",i);
                list.add(map);
            }
        }
        return list;
    }

    public static void main(String[] args) {
        ListMapToBeanTest a = new ListMapToBeanTest();
        List<Map<String,Object>> list = a.getTestData();
        System.out.println("原始数据:"+list);

        // 1
        List<TypeCountStatistics> r1 = a.listMapToBean(list);
        System.out.println("r1根据type过滤type=1后的统计结果:"+r1);

        Map<Long,Long> r2 = a.listMapToBean2(list);
        System.out.println("r2根据type过滤type=1后的统计结果:"+r2);

        Map<Integer,IntSummaryStatistics> r3 = a.listMapToBean3(list);
        System.out.println("r3根据type过滤type=1后的统计结果:"+r3);

        a.listMapToBean4(list);

        a.multiColumnStatistics(list);
    }
}
